﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GSPatEditor.Pat
{
    //TODO disposable
    class AnimationImageCache
    {
        private class SingleAnimationCache
        {
            //TODO share among SingleAnimationCache
            private Bitmap[] bitmaps;

            public SingleAnimationCache(AnimationImageCache parent, Animation animation)
            {
                bitmaps = new Bitmap[animation.FrameList.Count];

                for (int i = 0; i < bitmaps.Length; ++i)
                {
                    var frame = animation.FrameList[i];
                    var img = frame.Image;
                    Bitmap bitmap;
                    if (frame.ImageTransformation != null &&
                        frame.ImageTransformation.AlphaBlend == AlphaBlendOption.One)
                    {
                        bitmap = parent.CreateBlendBitmap(img.Image);
                    }
                    else
                    {
                        bitmap = parent.CreateNormalBitmap(img.Image);
                    }
                    if (img.ImageOffset.X + img.DisplaySize.X > bitmap.Width ||
                        img.ImageOffset.Y + img.DisplaySize.Y > bitmap.Height)
                    {
                        //TODO create a new one
                    }
                    bitmaps[i] = bitmap;
                }
            }

            public Bitmap Get(int index)
            {
                return bitmaps[index];
            }
        }

        private Palette palette;
        private Dictionary<Animation, SingleAnimationCache> animations =
            new Dictionary<Animation, SingleAnimationCache>();

        private Dictionary<Image, Bitmap> normalBitmapCache = new Dictionary<Image, Bitmap>();
        private Dictionary<Image, Bitmap> blendBitmapCache = new Dictionary<Image, Bitmap>();

        public AnimationImageCache(Palette palette)
        {
            this.palette = palette;
        }

        private void CacheAnimation(Animation animation)
        {
            if (animations.ContainsKey(animation))
            {
                return;
            }
            InternalCacheAnimation(animation);
        }

        private void InternalCacheAnimation(Animation animation)
        {
            animations.Add(animation, new SingleAnimationCache(this, animation));
        }

        public Bitmap GetBitmapForAnimation(Animation animation, int frame)
        {
            if (!animations.ContainsKey(animation))
            {
                InternalCacheAnimation(animation);
            }
            return animations[animation].Get(frame);
        }

        private Bitmap CreateNormalBitmap(Image image)
        {
            if (normalBitmapCache.ContainsKey(image))
            {
                return normalBitmapCache[image];
            }
            var bitmap = image.CreateBitmapWithPalette(palette);
            normalBitmapCache.Add(image, bitmap);
            return bitmap;
        }

        private Bitmap CreateBlendBitmap(Image image)
        {
            if (normalBitmapCache.ContainsKey(image))
            {
                return normalBitmapCache[image];
            }
            var bitmap = image.CreateBitmapWithPalette(palette);
            MakeAlphaBlendBitmap(bitmap);
            normalBitmapCache.Add(image, bitmap);
            return bitmap;
        }

        private void MakeAlphaBlendBitmap(Bitmap bitmap)
        {
            for (int i = 0; i < bitmap.Width; ++i)
            {
                for (int j = 0; j < bitmap.Height; ++j)
                {
                    var c = bitmap.GetPixel(i, j);
                    var cc = Color.FromArgb((int)((c.R + c.G + c.B) / 3.0f), c);
                    bitmap.SetPixel(i, j, cc);
                }
            }
        }

        private static void Main()
        {
            var bitmap = new Bitmap(@"C:\Users\WZW\Desktop\背景.PNG");
            var bitmap2 = new Bitmap(@"E:\bg2.png");
            for (int i = 0; i < bitmap.Width; ++i)
            {
                for (int j = 0; j < bitmap.Height; ++j)
                {
                    var c1 = bitmap.GetPixel(i, j);
                    var c2 = bitmap2.GetPixel(i, j);
                    //var a = Math.Min(c.R, Math.Min(c.G, c.B));
                    //var cc = Color.FromArgb(a, Color.White);
                    float ratio = c2.A / 255.0f;
                    float r = c1.R - c2.R * ratio, g = c1.G - c2.G * ratio, b = c1.B - c2.B * ratio;
                    var cc = Color.FromArgb((int)Math.Max(r, 0), (int)Math.Max(g, 0), (int)Math.Max(b, 0));
                    bitmap.SetPixel(i, j, cc);
                }
            }
            bitmap.Save(@"E:\bg3.png");
        }
    }
}
